package com.example.experiment_2java.controller;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.experiment_2java.annotation.Role;
import com.example.experiment_2java.annotation.RoleAuthorization;
import com.example.experiment_2java.entity.Admin;
import com.example.experiment_2java.entity.Student;
import com.example.experiment_2java.persistence.AdminMapper;
import com.example.experiment_2java.persistence.StudentMapper;
import com.example.experiment_2java.util.result.DataResult;
import com.example.experiment_2java.util.result.code.Code;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.example.experiment_2java.util.JWTUtils.getToken;
import static com.example.experiment_2java.util.JWTUtils.verify;

@RestController
@RequestMapping("user")
public class UserController {
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private AdminMapper adminMapper;


    @RequestMapping("/login")
    public DataResult login(@RequestParam("userId") String userId, @RequestParam("password") String password) {
        Admin admin = adminMapper.selectById(userId);
        if (admin != null && admin.getPassword().equals(password)) {
            Map<String,String> map = new HashMap<>();
            Map<String,String> map2 = new HashMap<>();
            map.put("adminId",userId);
            map.put("role",Role.MANAGER.toString());
            String token = getToken(map);
            map2.put("token",token);
            return DataResult.successByMessage("登录成功",map2);
        }
        Student student = studentMapper.selectById(userId);
        if (student != null && student.getPassword().equals(password)) {
            Map<String,String> map = new HashMap<>();
            Map<String,String> map2 = new HashMap<>();
            map.put("cardId",userId);
            map.put("role",Role.USER.toString());
            String token = getToken(map);
            map2.put("token",token);
            return DataResult.successByMessage("登录成功",map2);
        }
        return DataResult.errByErrCode(Code.LOGIN_ERROR);
    }

    /**
     * 获取学生个人信息
     * 学生仅可查询个人信息，管理员可以查询任意学生信息
     *
     * @param cardId 学生卡号
     * @param token 登录凭证
     * @return
     */
    @GetMapping("/student")
    @RoleAuthorization(Role.USER)
    public DataResult getStudent(@RequestParam(value = "cardId", required = false) String cardId,
                                 @RequestParam(value = "token", required = true) String token) {
        DecodedJWT decodedJWT = verify(token);
        if (decodedJWT.getClaim("role").asString().equals("MANAGER")) {
            // 管理员
            if (cardId != null && !cardId.isEmpty()) {
                Student student = studentMapper.selectById(cardId);
                // 隐藏密码
                student.setPassword("***");
                return DataResult.successByData(student).setApiLink("/api");
            }
            List<Student> students = studentMapper.selectList(null);
            students.forEach(student -> student.setPassword("***"));
            return DataResult.successByDataArray(students).setApiLink("/api");
        }
        // 学生
        if (decodedJWT.getClaim("cardId").asString().equals(cardId)) {
            Student student = studentMapper.selectById(cardId);
            student.setPassword("***");
            return DataResult.successByData(student).setApiLink("/api");
        }
        return DataResult.errByErrCode(Code.PERMISSION_DENY).setApiLink("/api");
    }

    /**
     * 更新学生信息
     * 仅管理员可使用
     *
     * @param student
     * @return
     */
    @PutMapping("/student")
    @RoleAuthorization(Role.MANAGER)
    public DataResult updateStudent(@RequestBody Student student) {
        if (student.getCardId() == null) {
            return DataResult.err().setApiLink("/api");
        }
        if (studentMapper.updateById(student) > 0) {
            return DataResult.successByMessage("更新学生信息成功", null).setApiLink("/api");
        } else {
            return DataResult.err().setApiLink("/api");
        }
    }

    /**
     * 新增学生信息
     * 仅管理员可使用
     *
     * @param student
     * @return
     */
    @PostMapping("/student")
    @RoleAuthorization(Role.MANAGER)
    public DataResult addStudent(@RequestBody Student student) {
        if (studentMapper.insert(student) > 0) {
            return DataResult.successByMessage("新增学生信息成功", null).setApiLink("/api");
        } else {
            return DataResult.err().setApiLink("/api");
        }
    }


    /**
     * 删除学生信息
     *
     * @param cardId
     * @return
     */
    @DeleteMapping("/student")
    @RoleAuthorization(Role.MANAGER)
    public DataResult deleteStudent(@RequestParam(value = "cardId") String cardId) {
        if (studentMapper.deleteById(cardId) > 0) {
            return DataResult.successByMessage("删除学生信息成功", null).setApiLink("/api");
        } else {
            return DataResult.err().setApiLink("/api");
        }
    }


    /**
     * 查询管理员信息
     * 仅可查询自己
     *
     * @param adminId
     * @param token
     * @return
     */
    @GetMapping("/admin")
    @RoleAuthorization(Role.MANAGER)
    public DataResult getAdmin(@RequestParam(value = "adminId", required = false) String adminId,
                               @RequestParam(value = "token", required = true) String token){
        DecodedJWT decodedJWT = verify(token);
        // 管理员
        if (adminId != null && !adminId.isEmpty()) {
            if (adminId.equals(decodedJWT.getClaim("adminId").asString())) {
                Admin admin = adminMapper.selectById(adminId);
                // 隐藏密码
                admin.setPassword("***");
                return DataResult.successByData(admin).setApiLink("/api");
            } else {
                return DataResult.errByErrCode(Code.PERMISSION_DENY).setApiLink("/api");
            }
        }
        adminId = decodedJWT.getClaim("adminId").asString();
        Admin admin = adminMapper.selectById(adminId);
        // 隐藏密码
        admin.setPassword("***");
        return DataResult.successByData(admin).setApiLink("/api");
    }
}
